package com.sjz.test1;

import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

import org.junit.Test;
/*
 * 一、方法引用：若 Lambda 体中的功能，已经有方法提供了实现，可以使用方法引用
 * 			  （可以将方法引用理解为 Lambda 表达式的另外一种表现形式）
 * 
 * 1. 对象的引用 :: 实例方法名
 * 
 * 2. 类名 :: 静态方法名
 * 
 * 3. 类名 :: 实例方法名
 * 
 * 注意：
 * 	 ①方法引用所引用的方法的参数列表与返回值类型，需要与函数式接口中抽象方法的参数列表和返回值类型保持一致！
 * 	 ②若Lambda 的参数列表的第一个参数，是实例方法的调用者，第二个参数(或无参)是实例方法的参数时，格式： ClassName::MethodName
 * 
 * 二、构造器引用 :构造器的参数列表，需要与函数式接口中参数列表保持一致！
 * 
 * 1. 类名 :: new
 * 
 * 三、数组引用
 * 
 * 	类型[] :: new;
 * 
 * 
 */
public class MethodRef {
	//类名 :: 静态方法名
		@Test
		public void test1() { 
			Consumer<String> c =(x)->System.out.println(x);   //lambda表达式
			c.accept("zhangsan");
			System.out.println("*****************************************");
			PrintStream ps=System.out;
			Consumer<String>  cc=ps::println;
			cc.accept("zhaoliu");
			System.out.println("*****************************************");
			Consumer<String> c1 =System.out::print;
			c1.accept("lisi");
		}
		
		//对象的引用 :: 实例方法名
		@Test
		public void test2() {
			Employee employee =new Employee("zhaoliu");
			Supplier<String> s =() -> employee.getName();
			System.out.println(s.get());
			System.out.println("*******************");
			Supplier<String> s1 = employee::getName;
			System.out.println(s1.get());
		}
		
		//类名 :: 实例方法名
		@Test
		public void test3() {
			// boolean test(T t, U u);
			BiPredicate<String, String> bp= (x,y) ->x.equals(y);
			System.out.println(bp.test("x", "xxxx"));
			System.out.println("****************************");
			BiPredicate<String, String> bp1=String::equals;  //方法引用
			System.out.println(bp1.test("x", "x"));
			System.out.println("****************************");
			Function<Employee, String> fun = (e) -> e.show();
			System.out.println(fun.apply(new Employee()));
			System.out.println("****************************");
			Function<Employee, String> fun2=Employee::show;   
			//<Employee, String>   泛型的第一个参数是传入参数  第二个参数是返回值
			System.out.println(fun2.apply(new Employee()));
		}
		
		//类名 :: 静态方法名
		@Test
		public void test4() {
			//int compare(T o1, T o2);
			Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
			System.out.println(com.compare(1, 3));
			System.out.println("-------------------------------------");
			Comparator<Integer> c =Integer::compare;
			System.out.println(c.compare(1, 3));
			
		}
		//类名 :: 静态方法名
		@Test
		public void test5() {
			BiFunction<Double, Double, Double> f1=(x,y)->Math.max(x, y);   //泛型的前两个参数是 方法的参数  最后一个是返回值的类型
			//R apply(T t, U u);   
			System.out.println(f1.apply(10.1, 11.2));
			System.out.println("********************************************");
			BiFunction<Double, Double, Double> f2 =Math::max;
			System.out.println(f2.apply(10.1, 11.2));
		}
		
		
		//类名 :: new  构造器引用
		@Test
		public void test6() {
			//  T get();
			Supplier<Employee> s1= ()->new Employee();
			System.out.println(s1.get());
			System.out.println("*********************************");
			Supplier<Employee> s2 =Employee::new;
			System.out.println(s2.get());
		}
		
		//类名 :: new  构造器引用
		@Test
		public void test7() {
			Function<String, Employee> fun =(x)->new Employee();
			System.out.println(fun.apply("1"));
			System.out.println("*******************************");
			Function<String, Employee> fun1 =Employee::new;
			System.out.println(fun1.apply("1"));
			System.out.println("*******************************");
			BiFunction<String, Integer, Employee> fun3= Employee::new;
			System.out.println(fun3.apply("22", 3));
		}
		
		////数组引用
		@Test
		public void test8() {
			Function<Integer, String[]> fun = (args) -> new String[args];
			String[] strs = fun.apply(10);
			System.out.println(strs.length);
			System.out.println("--------------------------");
			
			Function<Integer, String[]> fun1 =String[]::new;
			String[] st= fun1.apply(10);
			System.out.println(st.length);
			
		}
		
		
}
